/**
 * 删除特化接口测试用例
 *
 * Created by yangyunze on 2021/01/04.
 */
const chai = require('chai');
const should = chai.should(); // eslint-disable-line no-unused-vars
chai.use(require('chai-http'));

const common = require('./../../common');
const Administrator = require('./../../../models/administrator');
const uri = require('./../uri');
const benchmark = require('./../../../benchmark/analyse-files/specialization');

module.exports = describe('/DELETE file-elements/:id.json', function () {
  const administrator = new Administrator();
  let projectVersion = {};
  let specializedData = {};
  let fileElements = [];
  const newUserIds = [];
  function specializeUrl(fileId) {
    return `/files/${fileId}/file-elements.json`;
  }
  function url(elementId) {
    return `/file-elements/${elementId}.json`;
  }

  function getElement(fileElements, name) {
    let elementId = null;
    let fileId = null;
    fileElements.forEach((element) => {
      if (element.functionName !== name) {
        return;
      }
      elementId = element.functionId;
      fileId = element.fileId;
    });
    return { fileId, elementId };
  }

  before(function (done) {
    administrator.login()
      .then(() => administrator.createRandomTester())
      .then((tester) => {
        newUserIds.push(tester.userId);
        return tester.createRandomProject('c++');
      })
      .then((project) => project.createRandomVersion('c++'))
      .then((res) => {
        projectVersion = res;
        return projectVersion.getAllFunctions(benchmark);
      })
      .then((elements) => {
        fileElements = elements;
        return new Promise((resolve) => {
          const { elementId, fileId } = getElement(elements, benchmark.specialization.normal.name);
          const { requestBody } = benchmark.specialization.normal;
          requestBody.fileElementId = elementId;
          chai.request(uri)
            .post(specializeUrl(fileId))
            .set('Authorization', `Bearer ${projectVersion.project.creator.token.accessToken}`)
            .send(requestBody)
            .end((err, res) => {
              res.should.have.status(200);
              common.should.be.specializedElement(res.body);
              specializedData = res.body;
              resolve();
            });
        });
      })
      .then(done)
      .catch(done);
  });
  after(function (done) {
    administrator.removeUsers(newUserIds)
      .then(() => {
        done();
      })
      .catch(done);
  });

  common.should.be.user(uri, url, 'delete');
  common.should.be.tester(uri, url, 'delete');

  // 不可删除他人项目中的特化元素
  it('it should fail to delete a specialized element which not belong to your project', function (done) {
    let newUser;
    administrator.createRandomTester()
      .then((newTester) => {
        newUserIds.push(newTester.userId);
        newUser = newTester;
        return newUser.getToken();
      })
      .then(() => new Promise((resolve) => {
        chai.request(uri)
          .delete(url(specializedData.functionId))
          .set('Authorization', `Bearer ${newUser.token.accessToken}`)
          .end((err, res) => {
            res.should.have.status(404);
            common.should.be.errorMessage(res.body);
            resolve();
          });
      }))
      .then(() => projectVersion.project.creator.login())
      .then(done)
      .catch(done);
  });

  // 删除特化元素
  it('it should DELETE specialized element successfully', function (done) {
    new Promise((resolve) => {
      chai.request(uri)
        .delete(url(specializedData.functionId))
        .set('Authorization', `Bearer ${projectVersion.project.creator.token.accessToken}`)
        .end((err, res) => {
          res.should.have.status(204);
          resolve();
        });
    })
      .then(() => {
        chai.request(uri)
          .get(url(specializedData.functionId))
          .set('Authorization', `Bearer ${projectVersion.project.creator.token.accessToken}`)
          .end((err, res) => {
            res.should.have.status(404);
            done();
          });
      });
  });

  // 不可删除非特化元素
  it('it should fail to delete a non-specialized element', function (done) {
    const [{ functionId }] = fileElements;
    chai.request(uri)
      .delete(url(functionId))
      .set('Authorization', `Bearer ${projectVersion.project.creator.token.accessToken}`)
      .end((err, res) => {
        res.should.have.status(412);
        common.should.be.errorMessage(res.body);
        done();
      });
  });

  // 元素不存在
  it('it should fail to delete when specialized element not exists', function (done) {
    chai.request(uri)
      .delete(url('000000000000000000000000'))
      .set('Authorization', `Bearer ${projectVersion.project.creator.token.accessToken}`)
      .end((err, res) => {
        res.should.have.status(404);
        common.should.be.errorMessage(res.body);
        done();
      });
  });
});
